import ast
import json
import os
import subprocess
import pandas as pd
import cv2 as cv
from PyQt5.QtWidgets import QMainWindow, QGraphicsScene, QGraphicsPixmapItem
from PyQt5.QtGui import QPixmap, QImage, QCursor
from PyQt5.QtCore import Qt
from skimage.metrics import structural_similarity
from UI.ui_show_img import Ui_show_img


def create_path(path):
    is_exists = os.path.exists(path)
    if not is_exists:
        os.makedirs(path)


def run_cmd(cmd):
    ret = subprocess.getoutput(cmd)
    return ret


def open_path(path):
    if os.path.exists(path):
        cmd = 'xdg-open '+'"'+path+'"'
        run_cmd(cmd)


def save_json(file_name, data: dict):
    json_str = json.dumps(data, indent=4, ensure_ascii=False)
    with open(file_name, 'w') as json_file:
        json_file.write(json_str)


def count_file(path, suffix):
    number = 0
    if os.path.exists(path):
        for _, _, filenames in os.walk(path):
            for filename in filenames:
                if os.path.splitext(filename)[1] == suffix:
                    number += 1
    return number


def find_file(path, suffix):
    number = 0
    file_path = []
    if os.path.exists(path):
        for root, dirs, filenames in os.walk(path):
            for filename in filenames:
                if os.path.splitext(filename)[1] == suffix:
                    number += 1
                    file_path.append(os.path.join(root, filename))
    return file_path


def rect_img(path, roi, flag=0):
    try:
        roi = ast.literal_eval(roi)
        print("####绘制比对区域####", roi)
        roi_img = cv.imread(path)
        if flag == 1:
            cv.rectangle(roi_img, roi[0], roi[1], (0, 0, 255), 1)
            # cv.imwrite(path, roi_img)
    except:
        pass


def get_roi_mat(image, data, step):
    df = pd.read_csv(data, index_col=0)
    if '比对区域' not in df.columns.to_list():
        df.columns.to_list().insert(4, '比对区域')
        df.reindex(columns=df.columns.to_list())
        df.insert(loc=4, column='比对区域', value='')
    if '相似度' not in df.columns.to_list():
        df.columns.to_list().insert(5, '相似度')
        df.reindex(columns=df.columns.to_list())
        df.insert(loc=5, column='相似度', value='nan')
    if '结果' not in df.columns.to_list():
        df.columns.to_list().insert(6, '结果')
        df.reindex(columns=df.columns.to_list())
        df.insert(loc=6, column='结果', value='nan')
        df.to_csv(data, columns=df.columns.to_list(), encoding='utf_8_sig')
    df['比对区域'] = df['比对区域'].astype('object')
    roi = df.at[int(step), '比对区域']
    img = cv.imread(image, cv.IMREAD_GRAYSCALE)
    img = cv.GaussianBlur(img, (1, 1), 0)
    img_w = img.shape[0]
    img_h = img.shape[1]
    if not pd.isna(roi):
        area_pos = ast.literal_eval(roi)
        min_x = area_pos[0][0]
        min_y = area_pos[0][1]
        width = abs(area_pos[0][0]-area_pos[1][0])
        height = abs(area_pos[0][1]-area_pos[1][1])
        roi_mat = img[min_y:min_y+height, min_x:min_x+width]
        # cv.imwrite(str(step)+"select-area-image.png", roi_mat)
        return roi_mat
    else:
        # # cv.imwrite("desktop.png", img[0:int(img_w)-40, 120:img_h])
        # ret = imnore_area(img)
        # if ret <= 0.4:
        #     res = img[0:int(img_w)-40, 0:img_h]
        #     # cv.imwrite("ignore1.png",res)
        #     return res
        # else:
        #     res = img[0:int(img_w)-40, 120:img_h]
        #     # cv.imwrite("ignore2.png",res)
        #     return res
        return img[0:int(img_w)-40, 0:img_h]


def imnore_area(src):
    ignore = cv.imread('/opt/lance/ignore.png', cv.IMREAD_GRAYSCALE)
    h, w = ignore.shape[:2]
    methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR',
               'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']
    res = cv.matchTemplate(src, ignore, cv.TM_SQDIFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
    top_left = list(min_loc)
    find_img = src[top_left[1]:top_left[1]+h, top_left[0]:top_left[0]+w]
    if ignore.shape[0] < 5 or ignore.shape[1] < 5:
        ignore = cv.resize(ignore, (7, 7))
    if find_img.shape[0] < 5 or find_img.shape[1] < 5:
        find_img = cv.resize(find_img, (7, 7))
    score, _ = structural_similarity(
        im1=ignore, im2=find_img, win_size=3, gaussian_weights=True, full=True)  # , K1=0.1, K2=0.1)
    return score


class ImageShow(QMainWindow, Ui_show_img):
    def __init__(self, img):
        super().__init__()
        self.setupUi(self)
        self.retranslateUi(self)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowMaximizeButtonHint)
        scene = QGraphicsScene()
        result = cv.cvtColor(img, cv.COLOR_BGR2RGB)
        self.img_w = result.shape[1]
        self.img_h = result.shape[0]
        self.resize(result.shape[1]+10, result.shape[0]+10)
        self.move(1, 1)
        show_image = QImage(
            result.data, result.shape[1], result.shape[0], result.shape[1]*3, QImage.Format_RGB888)
        scene.clear()
        self.img_gv.setScene(scene)
        item = QGraphicsPixmapItem()
        item.setPixmap(QPixmap(show_image))
        scene.addItem(item)
        self.img_gv.setScene(scene)

    def wheelEvent(self, event):
        if self.img_gv.geometry().contains(self.mapFromGlobal(QCursor.pos())):
            img = self.img_gv.geometry()
            img_x = img.x()+self.img_w-5
            img_y = img.y() + self.img_h-5
            if event.pos().x() <= img_x and event.pos().y() <= img_y:
                if event.angleDelta().y() > 0:
                    self.img_gv.scale(1.09, 1.09)
                else:
                    self.img_gv.scale(0.91, 0.91)

    def closeEvent(self, event):
        event.accept()


allowed_subdirs = ['测试数据', 'code', '文档', '桌面', '音乐',
                   'miniconda3', '下载', '模板', '公共', '图片', '视频', 'sensors']


def get_visible_file(directory=None):
    top_level_items = []
    if directory == None:
        directory = os.path.expanduser('~')
    for entry in os.scandir(directory):
        if entry.name.startswith('.'):
            continue
        if entry.is_file() or (entry.is_dir() and not entry.is_symlink()):
            top_level_items.append(entry.name)
    for i in top_level_items:
        if i not in allowed_subdirs:
            old_file = os.path.join(directory, i)
            new_file = os.path.join(directory, '.'+i)
            os.rename(old_file, new_file)
